/**
 * @file color_print.h
 * @author Linquan  
 * @brief 
 * @version 1.0
 * @date 2024-06-18
 * 
 * @copyright Copyright (c) 2024
 * 
 */
#ifndef COLOR_PRINTF_H
#define COLOR_PRINTF_H

#include <stdio.h>

/** 
 * format :printf("\033[31m  This is red text  \033[0m"); 
 * “\033”   ：   开始转义,\033，也可以使用 \e 代替
 * “[31m”   ：   31代表颜色，4x代表背景色，m代表结束
 * “\033[0m”：  结束转义，恢复正常颜色 ，0代表默认颜色 ，m代表结束
 * 
 * string color:
    30 - 黑色
    31 - 红色
    32 - 绿色
    33 - 黄色
    34 - 蓝色
    35 - 紫红色
    36 - 青蓝色
    37 - 白色
 */

// 颜色、加粗
#define  RESET     "\e[0m"
#define  RED_BOLD       "\e[1;31m"
#define  GREEN_BOLD     "\e[1;32m"
#define  YELLOW_BOLD    "\e[1;33m"
#define  BLUE_BOLD      "\e[1;34m"
#define  PURPLE_BOLD    "\e[1;35m"
#define  CYAN_BOLD      "\e[1;36m"
#define  WHITE_BOLD     "\e[1;37m"
// 颜色 
#define  RED       "\e[31m"
#define  GREEN     "\e[32m"
#define  YELLOW    "\e[33m"
#define  BLUE      "\e[34m"
#define  PURPLE    "\e[35m"
#define  CYAN      "\e[36m"
#define  WHITE     "\e[37m"



void current_file(const char* _file_);
void current_line(int _line_);
void current_function(const char* _function_);
void current_time_second();
void current_time_us();
void color_printf(const char* color, const char* format, ...) ;
void assert_failed(const char* _file_, const char* _function_, int _line_);

void file_name_print(const char* _file_);
void line_print(int _line_);




// 颜色输出
#define   RED_PRINT(format, ... )       color_printf(RED, format, ##__VA_ARGS__)
#define   GREEN_PRINT(format, ... )     color_printf(GREEN, format, ##__VA_ARGS__)
#define   YELLOW_PRINT(format, ... )    color_printf(YELLOW, format, ##__VA_ARGS__)
#define   BLUE_PRINT(format, ... )      color_printf(BLUE, format, ##__VA_ARGS__)
#define   PURPLE_PRINT(format, ... )    color_printf(PURPLE, format, ##__VA_ARGS__)
#define   CYAN_PRINT(format, ... )      color_printf(CYAN, format, ##__VA_ARGS__)
#define   WHITE_PRINT(format, ... )     color_printf(WHITE, format, ##__VA_ARGS__)
// 加粗颜色输出
#define   B_RED_PRINT(format, ... )       color_printf(RED_BOLD, format, ##__VA_ARGS__)
#define   B_GREEN_PRINT(format, ... )     color_printf(GREEN_BOLD, format, ##__VA_ARGS__)
#define   B_YELLOW_PRINT(format, ... )    color_printf(YELLOW_BOLD, format, ##__VA_ARGS__)
#define   B_BLUE_PRINT(format, ... )      color_printf(BLUE_BOLD, format, ##__VA_ARGS__)
#define   B_PURPLE_PRINT(format, ... )    color_printf(PURPLE_BOLD, format, ##__VA_ARGS__)
#define   B_CYAN_PRINT(format, ... )      color_printf(CYAN_BOLD, format, ##__VA_ARGS__)
#define   B_WHITE_PRINT(format, ... )     color_printf(WHITE_BOLD, format, ##__VA_ARGS__)



// 输出 当前的所在的文件名、函数名、行号以及当前时间
#define CURRENT_FILE()        current_file(__FILE__);
#define CURRENT_LINE()        current_line(__LINE__);
#define CURRENT_FUNCTION()    current_function(__FUNCTION__ );
#define CURRENT_TIME_SECOND()   current_time_second();
#define CURRENT_TIME_US()      current_time_us();

/* printf system information */ 
#define SYSTEM_INFO_PRINT(format, ... )                \
        do{                                     \
            B_YELLOW_PRINT("[System info]: ");           \
            B_BLUE_PRINT(format, ##__VA_ARGS__); \
        } while (0)

/* printf debug log */                                    
#define DEBUG_INFO_PRINT(format, ... )                \
        do{                                     \
            B_PURPLE_PRINT("[Debug info]: ");           \
            B_WHITE_PRINT(format, ##__VA_ARGS__); \
        } while (0)                                   

/* printf error log */ 
#define ERROR_INFO_PRINT(format, ... )                \
        do{                                     \
            B_RED_PRINT("\n+++++++++++++++ Error log +++++++++++++++++++\n");   \
            file_name_print(__FILE__);                                          \
            line_print(__LINE__);                                               \
            B_CYAN_PRINT("[error]:"); B_YELLOW_PRINT(format, ##__VA_ARGS__);    \
            B_RED_PRINT("\n+++++++++++++  Error log end +++++++++++++++\n\n");    \
        } while (0)              


/**
 * @brief 断言
 * 
 */
#define ASSERT_PARAM(expr, format, ...) \
        do{           \
            (expr) ? (void)0 : \
            B_RED_PRINT("-------ASSERT FAIL!!!----\n");\
            assert_failed((const char *)__FILE__,__FUNCTION__,  __LINE__ );\
            B_YELLOW_PRINT(format, ##__VA_ARGS__);\
            printf("\r\n");\
            B_RED_PRINT("-------ASSERT   END------\n");\
        }while (0)
        
        



#endif